Thread: Istream::Release access violation? [C++]

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    85
    Quote Originally Posted by BobS0327 View Post
    Give this a try...

    Code:
    LPPICTURE gpPicture; 
    
    
    HBITMAP getFromInternet(std::string gal)
    {
    
        HBITMAP    hBitmap;
        HINTERNET      hInternet = InternetOpen( "GINA: Version 0.1", INTERNET_OPEN_TYPE_DIRECT, NULL, 0,0);
    
        std::string temp = gal  + ".overview.jpg";
        gal = "http://www.imperialconflict.com/images/Galaxies/";
        gal += temp;
        MessageBox(NULL,gal.c_str(),"",MB_OK);
        //get size of file
        HINTERNET     hFile = InternetOpenUrl(hInternet, gal.c_str(), NULL, 0, 0, 0);
        DWORD sizeBuffer;
        DWORD length = sizeof(sizeBuffer);
        BYTE *buffer = NULL;
    
        bool succeeds = HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&sizeBuffer, &length, NULL);
        if (!succeeds)
        {
            throw "Unable to fetch map";
            return (HBITMAP) NULL;
        }
        buffer = new BYTE[sizeBuffer];
    
        //initialize all elements to 0
        for (int i = 0; i < sizeBuffer; i++)
            buffer[i] = 0;
    
        LPVOID pvData = NULL; 
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeBuffer); 
        pvData = GlobalLock(hGlobal); 
        DWORD bytesRead;
        DWORD bytesToRead = sizeBuffer;
        if (hFile)
        {
            InternetReadFile(hFile, pvData, bytesToRead, &bytesRead);
        }
        else
            throw "Unable to grab overview image";
    
        GlobalUnlock(hGlobal); 
        CloseHandle(hFile); 
        LPSTREAM pstm = NULL; 
        // create IStream* from global memory 
        HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); 
        // Create IPicture from image file 
        if (gpPicture) 
            gpPicture->Release(); 
        hr = OleLoadPicture(pstm, sizeBuffer, FALSE, IID_IPicture, (LPVOID *)&gpPicture); 
        pstm->Release(); 
        gpPicture-> get_Handle ((OLE_HANDLE *) & hBitmap); 
        hBitmap = (HBITMAP) CopyImage (hBitmap, IMAGE_BITMAP, 0,0,0); 
        InternetCloseHandle(hFile);
        InternetCloseHandle(hInternet);
        return hBitmap;
    }
    Be advised that reading the pixels is not as simple and straighforward as you may think it is.


    Wow these have all been great responses. Unfortunately I've been away for a while as my system was rootkit-ed. It's been quite a battle to remove it. It disabled all current antivirus software and prevented the installation of new antivirus/antirootkit software.

    Anyways I originally had something that looked like the above. Then I read on msnd that OleLoadPicture only supports bitmaps, gifs, and icons. That led me to libjpeg.

    If you had a HBITMAP you could;

    Create a temp DC ( CreateCompatibleDC(NULL) )
    Select the HBITMAP into the DC (catching the returned default HBITMAP) with SelectObject()
    loop thru the pixels with GetPixel(),
    testing if each is 'blue' by using GetBValue(), GetRValue() and GetGValue()

    clean up by
    Selecting the default HBITMAP back into the DC
    then DeleteDC() on the mem DC
    That's perfect. I heard that GetPixel() can be a bit slow though. I'd need to check all the pixels in under 2 seconds. Do you think I could do that with a GetPixel() routine?

    GDI+ on the other hand can load more of the "exotic" standard image formats such as JPG, PNG, TIFF and GIF.
    Very very good post. I'd rather avoid GDI+. No particular reason. Just makes me 'icky'.

    I'm still experimenting with source managers and libjpeg. I found a source manager at http://www.groupsrv.com/science/about102031.html but I don't know of it's licensing so I'm writing my own with that one as a reference.

    I'll will post an update tomorrow. Thank you!

  2. #2
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Anyways I originally had something that looked like the above. Then I read on msnd that OleLoadPicture only supports bitmaps, gifs, and icons. That led me to libjpeg.
    Proof of concept code that proves OleLoadPicture supports jpeg. Right click on the image to change all the totally black pixels to totally white pixels.

    Code:
    #pragma comment( lib, "user32.lib" )
    #pragma comment( lib, "olepro32.lib" )
    #pragma comment( lib, "gdi32.lib" )
    #pragma comment( lib, "ole32.lib" )
    #pragma comment( lib, "Wininet.lib" )
    
    #include <windows.h> 
    #include <Wininet.h>
    #include <olectl.h> 
    
    #define COLORREF2RGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
                                    | ((Color << 16) & 0xff0000)
    
    LPPICTURE gpPicture; 
    HBITMAP hbm;
    
    HBITMAP ChangePixels(HBITMAP hBmp,COLORREF cOldColor,COLORREF cNewColor,HDC hBitmapDC)
    {
        HBITMAP hReturnBitmap = NULL;
        if (hBmp)
        {   
            HDC BufferDC=CreateCompatibleDC(NULL); 
            if (BufferDC)
            {
                HBITMAP hTempBitmap = (HBITMAP) NULL;
                if (hBitmapDC)
                    if (hBmp == (HBITMAP)GetCurrentObject(hBitmapDC, OBJ_BITMAP))
                    {
                        hTempBitmap = CreateBitmap(1, 1, 1, 1, NULL);
                        SelectObject(hBitmapDC, hTempBitmap);
                    }
                HGDIOBJ PreviousBuffer=SelectObject(BufferDC,hBmp);
                HDC DirectDC=CreateCompatibleDC(NULL); 
                if (DirectDC)
                {
                    BITMAP bm;
                    GetObject(hBmp, sizeof(bm), &bm);
                    BITMAPINFO BitmapInfo; 
                    ZeroMemory(&BitmapInfo,sizeof(BITMAPINFO));
                    BitmapInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
                    BitmapInfo.bmiHeader.biWidth=bm.bmWidth;
                    BitmapInfo.bmiHeader.biHeight=bm.bmHeight;
                    BitmapInfo.bmiHeader.biPlanes = 1;
                    BitmapInfo.bmiHeader.biBitCount = 32;
                    UINT * upPixels; 
                    HBITMAP DirectBitmap= CreateDIBSection(DirectDC, (BITMAPINFO *)&BitmapInfo, DIB_RGB_COLORS,(void **)&upPixels, NULL, 0);
                    if (DirectBitmap)
                    {
                        HGDIOBJ PreviousObject=SelectObject(DirectDC, DirectBitmap);
                        BitBlt(DirectDC,0,0,bm.bmWidth,bm.bmHeight,BufferDC,0,0,SRCCOPY);                   
                        char   cNewColorRef=COLORREF2RGB(cNewColor);
                        for (int iIndex = ((bm.bmWidth*bm.bmHeight) - 1); iIndex >= 0; iIndex--)
                            if (upPixels[iIndex] == cOldColor) upPixels[iIndex] = cNewColorRef;
                        SelectObject(DirectDC,PreviousObject);
                        hReturnBitmap=DirectBitmap;
                    }
                    DeleteDC(DirectDC);
                }           
                if (hTempBitmap)
                {
                    SelectObject(hBitmapDC, hBmp);
                    DeleteObject(hTempBitmap);
                }
                SelectObject(BufferDC,PreviousBuffer);
                DeleteDC(BufferDC);
            }
        }
        return hReturnBitmap;
    }
    
    HBITMAP getFromInternet(char *pURL)
    {
        HBITMAP    hBitmap;
        HINTERNET      hInternet = InternetOpen( "GINA: Version 0.1", INTERNET_OPEN_TYPE_DIRECT, NULL, 0,0);
        HINTERNET     hFile = InternetOpenUrl(hInternet, pURL, NULL, 0, 0, 0);
        DWORD sizeBuffer;
        DWORD length = sizeof(sizeBuffer);
    
        bool succeeds = HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&sizeBuffer, &length, NULL);
        if (!succeeds)
        {
            throw "Unable to fetch map";
            return (HBITMAP) NULL;
        }
        LPVOID pvData = NULL; 
        HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeBuffer); 
        pvData = GlobalLock(hGlobal); 
        DWORD bytesRead;
        DWORD bytesToRead = sizeBuffer;
        if (hFile)
        {
            InternetReadFile(hFile, pvData, bytesToRead, &bytesRead);
        }
        else
            throw "Unable to grab overview image";
        GlobalUnlock(hGlobal); 
        CloseHandle(hFile); 
        LPSTREAM pstm = NULL; 
        // create IStream* from global memory 
        HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); 
        // Create IPicture from image file 
        if (gpPicture) 
            gpPicture->Release(); 
        hr = OleLoadPicture(pstm, sizeBuffer, FALSE, IID_IPicture, (LPVOID *)&gpPicture); 
        pstm->Release(); 
        gpPicture-> get_Handle ((OLE_HANDLE *) & hBitmap); 
        hBitmap = (HBITMAP) CopyImage (hBitmap, IMAGE_BITMAP, 0,0,0); 
        InternetCloseHandle(hFile);
        InternetCloseHandle(hInternet);
        return hBitmap;
    }
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 
    
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) 
    { 
        static char szAppName[] = "JpegExample" ; 
        HWND hwnd; 
        MSG msg; 
        WNDCLASSEX wndclass; 
    
        int WinSize = 500; 
        int Left = 200; 
        int Top = 100; 
    
        wndclass.cbSize = sizeof (wndclass) ; 
        wndclass.style = CS_HREDRAW | CS_VREDRAW; 
        wndclass.lpfnWndProc = WndProc ; 
        wndclass.cbClsExtra = 0 ; 
        wndclass.cbWndExtra = 0 ; 
        wndclass.hInstance = hInstance ; 
        wndclass.hIcon = NULL ; 
        wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; 
        wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW) ; 
        wndclass.lpszMenuName = NULL ; 
        wndclass.lpszClassName = szAppName ; 
        wndclass.hIconSm = NULL ; 
    
        RegisterClassEx (&wndclass) ; 
    
        hwnd = CreateWindow ( 
            szAppName, 
            "Jpeg Example",
            WS_OVERLAPPEDWINDOW, 
            Left, 
            Top , 
            WinSize, 
            WinSize, 
            NULL, 
            NULL, 
            hInstance, 
            NULL 
            ) ; 
    
        ShowWindow (hwnd, iCmdShow); 
        UpdateWindow (hwnd); 
    
        while (GetMessage (&msg, NULL, 0, 0)) 
        { 
            TranslateMessage (&msg) ; 
            DispatchMessage (&msg) ; 
        } 
        return msg.wParam ; 
    } 
    
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 
    { 
        HDC hdc,hMemDC; 
        PAINTSTRUCT ps; 
        BITMAP bm;
        RECT MainRc;
        POINT pt;
        COLORREF colNew, colOld;
    
        switch (iMsg) 
        { 
            case WM_RBUTTONDOWN:
                colNew            = RGB(255,255,255);
                colOld            = RGB(0,0,0);
                hbm =  ChangePixels(hbm,colOld,colNew,NULL);
                InvalidateRect(hwnd, NULL, TRUE); 
                return 0;
            case WM_CREATE : 
                hbm = getFromInternet("http://www.imperialconflict.com/images/Galaxies/Capricorn.overview.jpg");
                return 0 ; 
            case WM_PAINT: 
                hdc = BeginPaint(hwnd, &ps); 
                GetClientRect(hwnd,&MainRc);
                hMemDC =  CreateCompatibleDC(hdc);
                SelectObject(hMemDC,hbm);
                GetObject(hbm,sizeof(BITMAP),&bm);
                pt.x = MainRc.right;
                pt.y = MainRc.bottom;
                SetStretchBltMode(hdc,COLORONCOLOR);
                StretchBlt(hdc,0,0,pt.x,pt.y,hMemDC,0,0,800,600,SRCCOPY);
                DeleteDC(hMemDC);
                EndPaint(hwnd, &ps);     
                return 0 ; 
            case WM_DESTROY : 
                PostQuitMessage (0) ; 
                return 0 ; 
        } 
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ; 
    }

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Cool

    Quote Originally Posted by BobS0327 View Post
    Proof of concept code that proves OleLoadPicture supports jpeg. Right click on the image to change all the totally black pixels to totally white pixels.
    . . .
    !!!
    You proved this page completely wrong! Edit: For anyone else reading this after, your example also needed uuid.lib linked
    http://msdn.microsoft.com/en-us/libr...24(VS.85).aspx

    Unless is there a provision for icons to use jpeg compression?

    Anyways this comes after I got a working solution with Libjpeg.

    The important part is the source manager here
    Code:
    #ifndef jpegSourceManager_H
    #define jpegSourceManager_H
    
    //modified from http://www.groupsrv.com/science/about102031.html
    
    #include <jpeglib.h>
    
    typedef struct MemSource
    {
           struct jpeg_source_mgr jsm;
           JOCTET * next_input_byte;
           size_t bytes_in_buffer;          
    }MemSource;
    
    static void initSource (j_decompress_ptr cinfo)
    {    
    }
    static boolean fillInputBuffer ( j_decompress_ptr cinfo)
    {
        //should never get here. Jpeg is bad if this happens
        throw "FillInputBuffer called. Jpeg Bad";
        return true;
    }
    static void skipInputData (j_decompress_ptr cinfo, long skipBytes)
    {
        //skipping bytes in stream that libjpeg doesn't care for
        MemSource *msm = (MemSource *)cinfo->src;
        msm->jsm.bytes_in_buffer = msm->bytes_in_buffer - skipBytes;
        msm->jsm.next_input_byte += skipBytes;            
    }
    static void doneWithSource (j_decompress_ptr cinfo)
    {}
    
    static void setUpSource( j_decompress_ptr cinfo, unsigned char *imageData, int length)
    {
           static MemSource mS;
           if (cinfo->src == NULL)
              cinfo->src = (struct jpeg_source_mgr *) &mS;
           MemSource *msm = (MemSource *)cinfo->src;
           msm->jsm.next_input_byte =         imageData;       
           msm->jsm.init_source =             initSource;
           msm->jsm.fill_input_buffer =       fillInputBuffer;
           msm->jsm.skip_input_data =         skipInputData;
           msm->jsm.term_source =             doneWithSource;
           msm->jsm.resync_to_restart =       jpeg_resync_to_restart; //provided by libjpeg
           msm->bytes_in_buffer =             msm->jsm.bytes_in_buffer = length;
           msm->next_input_byte =             imageData;
    }
    
    #endif
    Then the image is decompressed here.
    Note
    Code:
    #define ROW_SIZE     cinfo.output_width * 3
    Code:
    void Internet::loadImage(unsigned char* jpgData, int length)
    {
        	unsigned char *rawImage = NULL;
        	unsigned char *rawBuffer = NULL;
        	MapFile map;
        	/* these are standard libjpeg structures for reading(decompression) */
        	struct jpeg_decompress_struct cinfo;
        	struct jpeg_error_mgr jerr;
        	/* libjpeg data structure for storing one row, that is, scanline of an image */
        	cinfo.err = jpeg_std_error( &jerr );
        	jpeg_create_decompress( &cinfo );
        	//set up source manager so we can read from memory
        	setUpSource( &cinfo, jpgData, length );
        	jpeg_read_header( &cinfo, TRUE );
        	jpeg_start_decompress( &cinfo );
            
        	rawImage = new unsigned char[cinfo.output_height * ROW_SIZE];
        	rawBuffer = new unsigned char[ROW_SIZE];
        	
        	while (cinfo.output_scanline < cinfo.output_height)
            {
                  jpeg_read_scanlines( &cinfo, &rawBuffer, 1 );
                  memcpy(&rawImage[cinfo.output_scanline * ROW_SIZE], rawBuffer, ROW_SIZE);
            }
            
            //get image dimensions
            pMap->width = (cinfo.output_width - 8) / 8; //8 pixel border, 8 pixels per unit
            pMap->height = (cinfo.output_height - 8) / 8;
            char temp[50];
            MessageBox(NULL,itoa(pMap->height, temp, 10),"",MB_OK);
        	/* wrap up decompression, destroy objects, free pointers*/
        	jpeg_finish_decompress( &cinfo );
        	jpeg_destroy_decompress( &cinfo );
        	
        	delete [] rawImage;
        	delete [] rawBuffer;
        	delete [] jpgData;
        	return;
    }
    Last edited by A10; 01-14-2009 at 12:39 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Access Violation using memcmp?
    By someprogr in forum C Programming
    Replies: 3
    Last Post: 12-31-2007, 01:45 AM
  2. Access violation... can't figure it out...
    By Raigne in forum C++ Programming
    Replies: 7
    Last Post: 10-11-2007, 10:52 AM
  3. FtpFileFind access violation with MS VC++ 6.0
    By earth_angel in forum C++ Programming
    Replies: 3
    Last Post: 09-22-2005, 07:02 PM
  4. Strange access violation
    By jimmy_anttila in forum Windows Programming
    Replies: 2
    Last Post: 04-11-2004, 03:10 AM
  5. 0xC0000005: Access Violation
    By Strider in forum Windows Programming
    Replies: 3
    Last Post: 11-07-2001, 02:46 PM